package com.lingyu.jsjx.utils;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

public class ExcelImportUtil {

    /**
     * 导入Excel数据（使用Consumer函数式接口）
     *
     * @param file          上传的文件
     * @param dataProcessor 数据处理Consumer
     * @return 导入结果
     * @throws Exception 导入异常
     */
    public static String importExcelData(MultipartFile file, Consumer<List<Map<String, String>>> dataProcessor) throws Exception {
        return importExcelData(file, dataProcessor, true);
    }

    /**
     * 导入Excel数据（重载方法，可控制是否抛出异常）
     *
     * @param file           上传的文件
     * @param dataProcessor  数据处理Consumer
     * @param throwException 是否抛出异常
     * @return 导入结果
     * @throws Exception 导入异常
     */
    public static String importExcelData(MultipartFile file,
                                         Consumer<List<Map<String, String>>> dataProcessor,
                                         boolean throwException) throws Exception {
        // 检查文件是否为空
        if (file.isEmpty()) {
            return "导入文件不能为空";
        }

        // 检查文件格式
        String fileName = file.getOriginalFilename();
        if (fileName == null || (!fileName.endsWith(".xls") && !fileName.endsWith(".xlsx"))) {
            return "请上传Excel文件";
        }

        InputStream inputStream = null;
        Workbook workbook = null;
        List<Map<String, String>> dataList = new ArrayList<>();

        try {
            inputStream = file.getInputStream();

            // 根据文件后缀创建不同的Workbook
            if (fileName.endsWith(".xlsx")) {
                workbook = new XSSFWorkbook(inputStream);
            } else {
                workbook = new HSSFWorkbook(inputStream);
            }

            // 获取第一个sheet
            Sheet sheet = workbook.getSheetAt(0);

            // 读取表头（第一行）
            Row headerRow = sheet.getRow(0);
            List<String> headers = new ArrayList<>();
            for (Cell cell : headerRow) {
                headers.add(getCellValue(cell));
            }

            // 读取数据行（从第二行开始）
            for (int i = 1; i <= sheet.getLastRowNum(); i++) {
                Row row = sheet.getRow(i);
                if (row == null) continue;

                Map<String, String> rowData = new LinkedHashMap<>();
                for (int j = 0; j < headers.size(); j++) {
                    Cell cell = row.getCell(j);
                    rowData.put(headers.get(j), getCellValue(cell));
                }
                dataList.add(rowData);
            }

            // 处理数据 - 使用传入的Consumer
            dataProcessor.accept(dataList);

            return "导入成功，共导入 " + dataList.size() + " 条数据";

        } catch (Exception e) {
            if (throwException) {
                throw new Exception("导入失败：" + e.getMessage(), e);
            } else {
                return "导入失败：" + e.getMessage();
            }
        } finally {
            // 关闭资源
            if (workbook != null) {
                try {
                    workbook.close();
                } catch (Exception e) {
                }
            }
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (Exception e) {
                }
            }
        }
    }

    /**
     * 导入Excel数据（使用带异常处理的函数式接口）
     */
    public static String importExcelDataWithException(MultipartFile file,
                                                      ExcelDataProcessorWithException dataProcessor) throws Exception {
        List<Map<String, String>> dataList = parseExcel(file);

        try {
            dataProcessor.process(dataList);
            return "导入成功，共导入 " + dataList.size() + " 条数据";
        } catch (Exception e) {
            throw new Exception("导入失败：" + e.getMessage(), e);
        }
    }

    /**
     * 解析Excel文件（独立方法，可复用）
     */
    public static List<Map<String, String>> parseExcel(MultipartFile file) throws Exception {
        // 检查文件是否为空
        if (file.isEmpty()) {
            throw new Exception("导入文件不能为空");
        }

        String fileName = file.getOriginalFilename();
        if (fileName == null || (!fileName.endsWith(".xls") && !fileName.endsWith(".xlsx"))) {
            throw new Exception("请上传Excel文件");
        }

        try (InputStream inputStream = file.getInputStream();
             Workbook workbook = fileName.endsWith(".xlsx") ?
                     new XSSFWorkbook(inputStream) : new HSSFWorkbook(inputStream)) {

            Sheet sheet = workbook.getSheetAt(0);
            List<String> headers = new ArrayList<>();

            // 读取表头
            Row headerRow = sheet.getRow(0);
            for (Cell cell : headerRow) {
                headers.add(getCellValue(cell));
            }

            // 读取数据
            List<Map<String, String>> dataList = new ArrayList<>();
            for (int i = 1; i <= sheet.getLastRowNum(); i++) {
                Row row = sheet.getRow(i);
                if (row == null) continue;

                Map<String, String> rowData = new LinkedHashMap<>();
                for (int j = 0; j < headers.size(); j++) {
                    Cell cell = row.getCell(j);
                    rowData.put(headers.get(j), getCellValue(cell));
                }
                dataList.add(rowData);
            }

            return dataList;
        }
    }

    // 获取单元格值的方法保持不变...
    private static String getCellValue(Cell cell) {
        if (cell == null) {
            return "";
        }

        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue().trim();
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    return cell.getDateCellValue().toString();
                } else {
                    double numericValue = cell.getNumericCellValue();
                    if (numericValue == Math.floor(numericValue)) {
                        return String.valueOf((long) numericValue);
                    } else {
                        return String.valueOf(numericValue);
                    }
                }
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case FORMULA:
                return cell.getCellFormula();
            case BLANK:
                return "";
            default:
                return "";
        }
    }

    /**
     * 带异常处理的数据处理接口（函数式接口）
     */
    @FunctionalInterface
    public interface ExcelDataProcessorWithException {
        void process(List<Map<String, String>> dataList) throws Exception;
    }

    /**
     * 原来的数据处理接口（保持兼容性）
     */
    public interface ExcelDataProcessor {
        void processData(List<Map<String, String>> dataList) throws Exception;
    }
}